﻿/*
* This software is the confidential and proprietary
* information of NetBay
* Such confidential information should not be disclosed
* NetBay copyright(c) 2011
*/
#region Using
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using NetBay.Core.DataAccess;
using NetBay.Core.Extensions;
using NetBay.Core.Log;
using NetBay.Core.BusinessEntities.Workflow;

#endregion

namespace Rio.Flow.DataAccess
{
    public class DA_WorkflowModel
    {
        #region Enum
        /// <summary>
        /// List of DB functions to access data
        /// </summary>
        private enum DbFunction
        {
            [DescriptionAttribute("")]
            None,
            [DescriptionAttribute("P_WKF_MDLS_Get")]
            GetModels,
            [DescriptionAttribute("P_WKF_MDLS_Get_ByName")]
            GetModelByName,
            [DescriptionAttribute("P_WKF_MDLS_Get_ById")]
            GetModelById,
            [DescriptionAttribute("P_WKF_MDLS_ACT_Get_ById")]
            GetModelActions,
            [DescriptionAttribute("P_WKF_ACT_GET")]
            GetAllActions,
            [DescriptionAttribute("P_WKF_MDLS_COND_Get_ById")]
            GetModelConditions,
            [DescriptionAttribute("P_WKF_MDL_Add")]
            AddWorkflowModel,
            [DescriptionAttribute("P_WKF_MDL_ACT_COND_Add")]
            AddActionOrCondition,
            [DescriptionAttribute("P_WKF_MDL_Del")]
            DeleteModel,
            [DescriptionAttribute("P_WKF_COLOR_STATE_Get")]
            GetColorState, 
        }

        #endregion

        #region Functions

        /// <summary>
        /// Call P_WKF_MODELS_Get stored procedure
        /// </summary>
        /// <returns></returns>
        public static IDataReader GetWorkflowModels()
        {
            LogManager.Instance().LogDebug("Calling GetWorkflowModel()");

            var db = DbHelper.DataBase;
            var dbCommand = db.GetNewCommand(DbFunction.GetModels.szGetDescription());

            return db.ExecuteReader(dbCommand);
        }

        /// <summary>
        /// Calls P_WKF_MODELS_Get_ById stored procedure
        /// </summary>
        /// <param name="wkfModelId">The WKF model id.</param>
        /// <returns></returns>
        public static IDataReader GetWorkflowModelById(long wkfModelId)
        {
            LogManager.Instance().LogDebugFormat("(wkfModelId<{0}>)...", wkfModelId);

            var db = DbHelper.DataBase;
            var dbCommand = db.GetNewCommand(DbFunction.GetModelById.szGetDescription());
            db.AddInParameter(dbCommand, "p_lWkfMdlId", DbType.Int64, wkfModelId);

            return db.ExecuteReader(dbCommand);
        }

        /// <summary>
        /// Calls P_WKF_MODELS_Get_ByName stored procedure
        /// </summary>
        /// <param name="wkfModelName">Workflow model name</param>
        /// <returns></returns>
        public static IDataReader GetWorkflowModelByName(string wkfModelName)
        {
            LogManager.Instance().LogDebugFormat("(wkfModelName<{0}>)...", wkfModelName);

            var db = DbHelper.DataBase;
            var dbCommand = db.GetNewCommand(DbFunction.GetModelByName.szGetDescription());
            db.AddInParameter(dbCommand, "p_sWkfModelName", DbType.String, wkfModelName);

            return db.ExecuteReader(dbCommand);
        }

        /// <summary>
        /// Calls P_WKF_COLOR_STATE_Get
        /// </summary>
        /// <returns></returns>
        public static List<WorkflowStateInfo> GetWorkflowStateInfos()
        {
            LogManager.Instance().LogDebug("...");

            var db = DbHelper.DataBase;

            List<WorkflowStateInfo> statesColors = new List<WorkflowStateInfo>();
            using (var dbCommand = db.GetNewCommand(DbFunction.GetColorState.szGetDescription()))
            {
                using (IDataReader reader = db.ExecuteReader(dbCommand))
                {
                    while (reader.Read())
                    {
                        WorkflowStateInfo csl = new WorkflowStateInfo();
                        csl.Color = reader.GetStringValue("t_ref_wkf_state_color");
                        csl.State = reader.GetEnumValue<WorkflowState>("t_ref_wkf_state_id");
                        csl.Label = reader.GetStringValue("t_ref_wkf_state_name");
                        csl.Icon = reader.GetStringValue("t_ref_wkf_state_icon");

                        statesColors.Add(csl);
                    }
                }
            }

            return statesColors;
        }

        /// <summary>
        /// Calls P_WKF_MODELS_ACT_Get_ById stored procedure
        /// </summary>
        /// <param name="wkfModelID">The WKF model ID.</param>
        /// <returns></returns>
        public static IDataReader GetActions(long wkfModelID)
        {
            LogManager.Instance().LogDebugFormat("(wkfModelID<{0}>)...", wkfModelID);

            var db = DbHelper.DataBase;
            var dbCommand = db.GetNewCommand(DbFunction.GetModelActions.szGetDescription());
            db.AddInParameter(dbCommand, "p_lWkfMdlId", DbType.Int64, wkfModelID);

            return db.ExecuteReader(dbCommand);
        }

        /// <summary>
        /// Calls P_WKF_MODELS_ACT_Get_ById stored procedure
        /// </summary>
        /// <returns></returns>
        public static IDataReader GetAllActions()
        {
            LogManager.Instance().LogDebug("...");

            var db = DbHelper.DataBase;
            var dbCommand = db.GetNewCommand(DbFunction.GetAllActions.szGetDescription());

            return db.ExecuteReader(dbCommand);
        }

        /// <summary>
        /// Calls P_WKF_MODELS_COND_Get_ById stored procedure
        /// </summary>
        /// <param name="wkfModelID">The WKF model ID.</param>
        /// <returns></returns>
        public static IDataReader GetConditions(long wkfModelID)
        {
            LogManager.Instance().LogDebugFormat("(wkfModelID<{0}>)...", wkfModelID);

            var db = DbHelper.DataBase;
            var dbCommand = db.GetNewCommand(DbFunction.GetModelConditions.szGetDescription());
            db.AddInParameter(dbCommand, "p_lWkfMdlId", DbType.Int64, wkfModelID);

            return db.ExecuteReader(dbCommand);
        }

        /// <summary>
        /// Calls P_WKF_MODEL_Add stored procedure
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="actions">The actions.</param>
        /// <param name="conditions">The conditions.</param>
        /// <returns>True if ok</returns>
        public static bool AddWorkflowModel(WorkflowModel model, List<long> actions, List<long> conditions)
        {
            var l_bReturn = true;
            DbTransaction transaction = null;
            var db = DbHelper.DataBase;

            using (DbConnection connection_db_b = db.CreateConnection())
            {
                try
                {
                    connection_db_b.Open();
                    transaction = connection_db_b.BeginTransaction();

                    //Add model 
                    var dbCommand = db.GetNewCommand(DbFunction.AddWorkflowModel.szGetDescription());
                    db.AddInParameter(dbCommand, "p_lWkfTypeId", DbType.Int64, Convert.ToInt64(model.WorkflowType));
                    db.AddInParameter(dbCommand, "p_sWkflMdlName", DbType.String, model.Name);
                    db.AddInParameter(dbCommand, "p_sWkflMdlDesc", DbType.String, model.Description);
                    db.AddInParameter(dbCommand, "p_sWkflMdlClassname", DbType.String, model.ClassName);
                    db.AddInParameter(dbCommand, "p_sWkflMdlAssembly", DbType.String, model.AssemblyName);
                    db.AddInParameter(dbCommand, "p_sWkflMdlRules", DbType.String, model.Rules);

                    int newModelIdentifier = 0;
                    using (IDataReader reader = db.ExecuteReader(dbCommand, transaction))
                    {
                        while (reader.Read())
                        {
                            newModelIdentifier = Convert.ToInt32(reader["WKF_MDL_ID"]);
                        }
                    }

                    //Add Actions
                    foreach (var id in actions)
                    {
                        dbCommand = db.GetNewCommand(DbFunction.AddActionOrCondition.szGetDescription(), false);
                        db.AddInParameter(dbCommand, "p_lWkfMdlId", DbType.Int64, newModelIdentifier);
                        db.AddInParameter(dbCommand, "p_lWkfActCondId", DbType.Int64, Convert.ToInt32(id));
                        db.ExecuteNonQuery(dbCommand, transaction);
                    }

                    //Add Conditions
                    foreach (var id in conditions)
                    {
                        dbCommand = db.GetNewCommand(DbFunction.AddActionOrCondition.szGetDescription(), false);
                        db.AddInParameter(dbCommand, "p_lWkfMdlId", DbType.Int64, newModelIdentifier);
                        db.AddInParameter(dbCommand, "p_lWkfActCondId", DbType.Int64, Convert.ToInt32(id));
                        db.ExecuteNonQuery(dbCommand, transaction);
                    }

                    transaction.Commit();
                }
                catch (Exception ex)
                {
                    if (transaction != null)
                        transaction.Rollback();

                    l_bReturn = false;
                    LogManager.Instance().LogError("Exception -> " + Environment.NewLine + ex.Message);
                }
            }

            return l_bReturn;
        }

        /// <summary>
        /// Calls P_WKF_MODEL_ACT_COND_Add stored procedure
        /// </summary>
        /// <param name="wkfMdlId">Workflow model identifier</param>
        /// <param name="wkfActCondId">Model condition or action identifier</param>
        /// <returns>True if ok</returns>
        public static bool AddActionOrConditionToModel(long wkfMdlId, long wkfActCondId)
        {
            var l_bReturn = true;
            try
            {
                LogManager.Instance().LogDebug("(wkfMdlId<" + wkfMdlId + "> wkfActCondId<" + wkfActCondId + ">)");

                var db = DbHelper.DataBase;
                using (var dbCommand = db.GetNewCommand(DbFunction.AddActionOrCondition.szGetDescription(), false))
                {
                    db.AddInParameter(dbCommand, "p_lWkfMdlId", DbType.Int64, wkfMdlId);
                    db.AddInParameter(dbCommand, "p_lWkfActCondId", DbType.Int64, wkfActCondId);

                    db.ExecuteNonQuery(dbCommand);
                }
            }
            catch (Exception ex)
            {
                l_bReturn = false;
                LogManager.Instance().LogError("Exception -> " + Environment.NewLine + ex.Message);
            }
            return l_bReturn;
        }

        /// <summary>
        /// Calls P_WKF_INST_USR_Del stored procedure
        /// </summary>
        /// <param name="wkfModelId">The WKF model id.</param>
        /// <returns></returns>
        public static bool DeleteModel(long wkfModelId)
        {
            var l_bReturn = true;
            try
            {
                LogManager.Instance().LogDebug("(wkfModelId<" + wkfModelId + ">");

                var db = DbHelper.DataBase;
                using (var dbCommand = db.GetNewCommand(DbFunction.DeleteModel.szGetDescription(), false))
                {
                    db.AddInParameter(dbCommand, "p_lWkfMdlId", DbType.Int64, wkfModelId);

                    db.ExecuteNonQuery(dbCommand);
                }
            }
            catch (Exception ex)
            {
                l_bReturn = false;
                LogManager.Instance().LogError("Exception -> " + Environment.NewLine + ex.Message);
            }
            return l_bReturn;
        }
        #endregion
    }
}